#include "SimpleAppender.h"

#include <iostream>

#include "Topic.h"
#include "FileSize.h"
#include "recovery/fs/file/File.h"
#include "recovery/fs/file/FileAppender.h"

using recovery::Status;
using recovery::fs::file::FileAppender;
using recovery::fs::file::File;

SimpleAppender::SimpleAppender(Topic & topic)
: _topic(topic)
{
}

SimpleAppender::~SimpleAppender() {
}

bool SimpleAppender::open() {
	if(_topic.open() == 0){
		File f(_topic.logPath());
		if(f.exist()){
			return FileAppender::openExist(_topic.logPath(), _log);
		}
		else{
			return FileAppender::create(_topic.logPath(), _log);
		}
	}
	return false;
}
bool SimpleAppender::close() {
	_log->close();
	_topic.close();
	return true;
};

void SimpleAppender::recordAppendedBytes(const size_t appendedBytes) {
    _appendedBytes += appendedBytes;
}

void SimpleAppender::updateFileSize() {
    _topic.fileSize()->increase(_appendedBytes);
    _appendedBytes = 0;
}

std::pair<Status, size_t> SimpleAppender::append(const std::string & data){
	size_t appendedBytes = 0;
	const auto & s = _log->append(data + ";", appendedBytes);
    if (s) {
        recordAppendedBytes(appendedBytes); 
    }
	return std::make_pair(s.toStatus(), appendedBytes);
}
Status SimpleAppender::commit(){
	size_t appendedBytes = 0;
	const auto & s = _log->append("commit;", appendedBytes);
	if(s){
        recordAppendedBytes(appendedBytes); 
		const auto & s = _log->sync();
        if (s) {
            updateFileSize();
            return s.toStatus();
        }
        else {
		    return s.toStatus("sync failed");
        }
	}
	return s.toStatus("append commit info failed");
}
